package so.sao.code.service.web.isv;

import java.io.IOException;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import so.sao.auth.autoreg.annotation.IsvResource;
import so.sao.code.service.domain.CodeType;
import so.sao.code.service.domain.FileType;
import so.sao.code.service.domain.ThirdPartyCodeFileInfoProvider;
import so.sao.code.service.domain.ThirdPartyCodeFileInfoWrapper;
import so.sao.code.service.domain.UserBaseInfoWrapper;
import so.sao.code.service.infrastructure.model.vo.ThirdPartCodeFileVO;
import so.sao.code.service.infrastructure.stream.ProduceManager;
import so.sao.code.service.service.ThirdPartyCodeFileHandleService;
import so.sao.sso.bind.CurrentUser;
import so.sao.sso.feign.dto.IsvUserDTO;
import so.sao.top.core.util.exceptions.ServiceException;
import springfox.documentation.annotations.ApiIgnore;

@Api(value = "thirdpartycodefilehandle", tags = { "文件上传操作" })
@ApiResponses({ @ApiResponse(code = 200, message = "Successful — 请求已完成"),
		@ApiResponse(code = 400, message = "请求中有语法问题，或不能满足请求"), @ApiResponse(code = 401, message = "未授权客户机访问数据"),
		@ApiResponse(code = 404, message = "服务器找不到给定的资源；文档不存在"), @ApiResponse(code = 500, message = "服务器不能完成请求") })
@RestController
@RequestMapping("/isv/codefilehandle")
public class ThirdPartyCodeFileHandleController {

	private static Logger logger = LoggerFactory.getLogger(ThirdPartyCodeFileHandleController.class);

	@Resource(name="thirdPartyCodeFilePackageHandle")
	ThirdPartyCodeFileHandleService thirdPartyCodeFilePackageHandleService;
	
	@Resource(name="thirdPartyCodeFileMappingHandle")
	ThirdPartyCodeFileHandleService thirdPartyCodeFileMappingHandleService;
	
	@ApiOperation(value = "上传package文件到服务器-MultipartFile", produces = "application/json", consumes = "multipart/form-data", response = RespVO.class)
	@ApiImplicitParams({
			@ApiImplicitParam(name = "ccode", value = "客户公司code [a-zA-Z][a-zA-Z0-9]{0,9}", required = true, dataType = "String", paramType = "path"),
			@ApiImplicitParam(name = "tcode", value = "终端code [a-zA-Z0-9]{0,9}", required = true, dataType = "String", paramType = "path"),
			@ApiImplicitParam(name = "fileType", value = "文件类型：zip固定", required = true, dataType = "String", paramType = "form"),
			@ApiImplicitParam(name = "packageCount", value = "箱码数量", required = true, example = "1", dataType = "Integer", paramType = "form"),
			@ApiImplicitParam(name = "capCount", value = "瓶码数量", required = true, example = "6", dataType = "Integer", paramType = "form"),
			@ApiImplicitParam(name = "md5", value = "文件指纹", required = true, example = "xxxxxxxxxx", dataType = "String", paramType = "form"),
			@ApiImplicitParam(name = "codeType", value = "箱码类型:1(1-6),2(2-6),3(2-6-6)", required = true, example = "1", dataType = "Integer", paramType = "form") })

	@IsvResource(perm = "thirdpartycodefilehandle.upload-package", name = "上传package文件到服务器")
	@PostMapping(value = "/package/company/{ccode}/terminal/{tcode}")
	public ResponseEntity<RespVO> uploadPackage(@ApiIgnore @CurrentUser IsvUserDTO dto,
			@RequestParam("file") MultipartFile file, @ApiIgnore ThirdPartCodeFileVO rex,@PathVariable String ccode,@PathVariable String tcode) {
		IsvUserDTO user = dto;
		// TODO 假数据 --start
		if (user == null) {
			user = new IsvUserDTO();
			user.setEseId(1L);
			user.setId(100L);
			user.setTerminalId(tcode);
			user.setCompanyId(1L);
		}else{
			if(user.getEseId()==null){
				logger.info("user.getEseId()=null. set default value：1");
				user.setEseId(1L);
			}
			if(user.getTerminalId()==null){
				logger.info("user.getTerminalId()=null. to set path value");
				user.setTerminalId(tcode);;
			}
			
		}
		// TODO 假数据 --end
		
		RespVO uploadResponse = new RespVO(1, "success");
		ThirdPartyCodeFileInfoProvider wapper = null;
		UserBaseInfoWrapper usebaseInfo = null;
		try {
			
			if (file != null) {
				rex.setFileName(file.getOriginalFilename());
				try {
					byte[] bytes = file.getBytes();
					rex.setFileSize(bytes.length);
				} catch (IOException e) {
				}
			}

			// 校验输入。
			try {
				thirdPartyCodeFilePackageHandleService.validate(user, file, rex);
			} catch (ServiceException e1) {
				uploadResponse = new RespVO(2, e1.getMessage());
				return ResponseEntity.ok(uploadResponse);
			}

			// 获取用户基本信息。
			usebaseInfo = thirdPartyCodeFilePackageHandleService.wrapUsebaseInfo(user);
			if (usebaseInfo == null) {
				uploadResponse = new RespVO(2, "非法用户");
				return ResponseEntity.ok(uploadResponse);
			}

			// 保存文件
			wapper = new ThirdPartyCodeFileInfoWrapper();
			wapper.setCapCount(rex.getCapCount());
			wapper.setPackageCount(rex.getPackageCount());
			wapper.setCodeType(CodeType.get(rex.getCodeType()));
			wapper.setMd5(rex.getMd5());
			wapper.setFileType(FileType.get(rex.getFileType()));
			try {
				wapper = thirdPartyCodeFilePackageHandleService.saveFile(usebaseInfo, wapper, file);
			} catch (ServiceException e) {
				uploadResponse = new RespVO(2, e.getMessage());
				return ResponseEntity.ok(uploadResponse);
			}

		} finally {
			// 日志一定要记录。
			logger.info("请求接口：/package；参数:" + rex.toString());
		}

		// 对文件做处理。
		thirdPartyCodeFilePackageHandleService.doAsyncProcess(usebaseInfo, wapper);

		return ResponseEntity.ok(uploadResponse);
	}
	
	@ApiOperation(value = "上传mapping文件到服务器-MultipartFile", produces = "application/json", consumes = "multipart/form-data", response = RespVO.class)
	@ApiImplicitParams({
			@ApiImplicitParam(name = "ccode", value = "客户公司code [a-zA-Z][a-zA-Z0-9]{0,9}", required = true, dataType = "String", paramType = "path"),
			@ApiImplicitParam(name = "tcode", value = "终端code [a-zA-Z0-9]{0,9}", required = true, dataType = "String", paramType = "path"),
			@ApiImplicitParam(name = "fileType", value = "文件类型：zip固定", required = true, dataType = "String", paramType = "form"),
			@ApiImplicitParam(name = "md5", value = "文件指纹", required = true, example = "xxxxxxxxxx", dataType = "String", paramType = "form"),
			@ApiImplicitParam(name = "codeType", value = "30:mapping", required = true, example = "30", dataType = "Integer", paramType = "form") })
	
	@IsvResource(perm = "thirdpartycodefilehandle.upload-mapping", name = "上传mapping文件到服务器")
	@PostMapping(value = "/mapping/company/{ccode}/terminal/{tcode}")
	public ResponseEntity<RespVO> uploadMapping(@ApiIgnore @CurrentUser IsvUserDTO dto,
			@RequestParam("file") MultipartFile file, @ApiIgnore ThirdPartCodeFileVO rex,@PathVariable String ccode,@PathVariable String tcode) {
		IsvUserDTO user = dto;
		// TODO 假数据 --start
		if (user == null) {
			user = new IsvUserDTO();
			user.setEseId(1L);
			user.setId(100L);
			user.setTerminalId(tcode);
			user.setCompanyId(1L);
		}else{
			if(user.getEseId()==null){
				logger.info("user.getEseId()=null. set default value：1");
				user.setEseId(1L);
			}
			if(user.getTerminalId()==null){
				logger.info("user.getTerminalId()=null. to set path value");
				user.setTerminalId(tcode);;
			}
			
		}
		// TODO 假数据 --end
		
		RespVO uploadResponse = new RespVO(1, "success");
		ThirdPartyCodeFileInfoProvider wapper = null;
		UserBaseInfoWrapper usebaseInfo = null;
		try {
			
			if (file != null) {
				rex.setFileName(file.getOriginalFilename());
				try {
					byte[] bytes = file.getBytes();
					rex.setFileSize(bytes.length);
				} catch (IOException e) {
				}
			}

			// 校验输入。
			try {
				thirdPartyCodeFileMappingHandleService.validate(user, file, rex);
			} catch (ServiceException e1) {
				uploadResponse = new RespVO(2, e1.getMessage());
				return ResponseEntity.ok(uploadResponse);
			}

			// 获取用户基本信息。
			usebaseInfo = thirdPartyCodeFileMappingHandleService.wrapUsebaseInfo(user);
			if (usebaseInfo == null) {
				uploadResponse = new RespVO(2, "非法用户");
				return ResponseEntity.ok(uploadResponse);
			}

			// 保存文件
			wapper = new ThirdPartyCodeFileInfoWrapper();
			wapper.setCapCount(rex.getCapCount());
			wapper.setPackageCount(rex.getPackageCount());
			wapper.setCodeType(CodeType.get(rex.getCodeType()));
			wapper.setMd5(rex.getMd5());
			wapper.setFileType(FileType.get(rex.getFileType()));
			try {
				wapper = thirdPartyCodeFileMappingHandleService.saveFile(usebaseInfo, wapper, file);
			} catch (ServiceException e) {
				uploadResponse = new RespVO(2, e.getMessage());
				return ResponseEntity.ok(uploadResponse);
			}

		} finally {
			// 日志一定要记录。
			logger.info("请求接口：/package；参数:" + rex.toString());
		}

		return ResponseEntity.ok(uploadResponse);
	}
	
	
	//TODO TEST
	@Autowired
	private ProduceManager produceManager;

	@PostMapping(value = "/xxxx")
	public ResponseEntity<RespVO> multipartFileUpload3(){
		RespVO uploadResponse = new RespVO(1, "success");
		produceManager.send("cccc"); //或
		produceManager.send("xxxxxx",1000l);
		return ResponseEntity.ok(uploadResponse);
	}
	

	class RespVO {

		RespVO(Integer state, String msg) {
			this.state = state;
			this.msg = msg;
		}

		RespVO() {
		}

		Integer state;
		String msg;

		public Integer getState() {
			return state;
		}

		public void setState(Integer state) {
			this.state = state;
		}

		public String getMsg() {
			return msg;
		}

		public void setMsg(String msg) {
			this.msg = msg;
		}

	}

}
